#ifndef BASEDEFINITIONS
#define BASEDEFINITIONS

#ifdef CHECKMEM
#include "nommgr.h"
#endif

#define _CRT_SECURE_NO_DEPRECATE 1

#include <string>
#include <vector>
#include <set>
#include <fstream>
#include <list>
#include <map>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <math.h>
#include <boost/signal.hpp>
#include <boost/bind.hpp>

#include <assert.h>

#ifdef BUILDLIBRARY
#include <boost/lexical_cast.hpp>
#include <png.h>
///We need the glext.h defines for the Renderer, in future i might make the Renderer a plugin and remove the need for glext.h. glfw.h is required for glext.h to work properly.
#include <gl/glfw.h>
#include <gl/glext.h>
#include <ft2build.h>
#include FT_FREETYPE_H
extern "C" {
#include <jpeglib.h>
}
#endif

// disable: "<type> needs to have dll-interface to be used by clients'
// Happens on STL member variables which are not public therefore is ok
#   pragma warning (disable : 4251)
 

#ifdef SYPDLL
//This is to be used for the class header file.
	#define SYPAPI __declspec(dllexport)
	#define EXPIMP_TEMPLATE
#else
	//FreeType2 defines only when using DLL, since we dont want to include freetype.h
	struct FT_LibraryRec_;
	struct FT_FaceRec_;
	typedef struct FT_FaceRec_*  FT_Face;
	typedef struct FT_LibraryRec_  *FT_Library;
	#ifdef USESYPDLL
		#define SYPAPI __declspec(dllimport)
		#define EXPIMP_TEMPLATE extern
	#else
		#define SYPAPI
		#define EXPIMP_TEMPLATE
	#endif
#endif

#ifndef USESYPDLL	
	/////////////////////Linking pragmas///////////////////
	#pragma comment(lib, "user32.lib") 
	#pragma comment(lib, "opengl32.lib") 
	#pragma comment(lib, "glfw.lib") 
	#pragma comment(lib, "glu32.lib") 
	#pragma comment(lib, "libpng.lib")
	#pragma comment(lib, "zlib.lib")
	#pragma comment(lib, "libjpeg.lib")
	#pragma comment(lib, "freetype221MT.lib")
	//////////////////////////////////////////////////////////////////	
#endif

#include "GE_Math.h"

namespace Syp
{
class Node;
struct MeshInstance;
struct KeyFrame;
struct KeyEvent;
struct IndexBlock;
struct SubMaterial;
struct MouseState;

class Resource;
class SypEngine;
class Renderer;
class ErrorLogger;
class Math;
class Font;
class BaseMesh;
class IndexedMesh;
class NIndexedMesh;
class TextureObj;
class Material;
class SceneManager;
class ResourceManager;
class Renderable;
class Camera;
class Shader;
class ShaderProgram;
class VertexShader;
class PixelShader;
class Pass;
class Effect;
class PassRegistry;
class EffectRegistry;
class Light;
class FontRegistry;
class GuiBase;
class Button;
class Frame;
class Skeleton;
class Label;


struct Point3;
struct Point4;
struct Bone;



///Describes color using RGB components
struct Color3f
{
	///If you see freen stuff, you noe it's an uninitialised Color
	Color3f()
	{
		r = 0.0f;
		g = 1.0f;
		b = 0.0f;
	};
	float r;
	float g;
	float b;
};
///Describes color using RGBA components
struct Color4f : public Color3f
{
	Color4f()
	{
		a = 1.0f;
	}
	float a;
};

///String
typedef std::string String;
///Positive integer
typedef unsigned int PInt;
///Byte
typedef char Byte;
///Positive byte
typedef unsigned char PByte;
///Positive Short Array
typedef unsigned short PShort;
///Array of floats
typedef std::vector<float> FloatArray;
///Positive integer or unsigned int
typedef std::vector<unsigned int> PIntArray;
///Integer Array
typedef std::vector<int> IntArray;
///Positive Short array
typedef std::vector<unsigned short> PShortArray;
///Short Array
typedef std::vector<short> ShortArray;
typedef std::ostringstream StringBuffer;

typedef int SYPThread;
typedef void * SYPMutex;
typedef void (*SYPThreadFunction)(void *);
typedef void (*SYPWindowCloseFunction)(void);


///Positive byte
typedef std::vector<unsigned char> PByteArray;

///Byte Array
typedef std::vector<char> ByteArray;

///Describes the format of the indices. 
enum RenderingFormat{
	FORMAT_TRISTRIP = 0x0005,
	FORMAT_TRIANGLES = 0x0004,
	FORMAT_QUADS = 0x0007,
	
};
///Different blend types a mesh can have
///NOBLEND means no blending will be used at all
///ALPHA refers to either it is visible/not visible mode. Use this mode if mesh is using textures with alpha values 0 and 255 only.Fonts/Billboards should make use of this.
///BLEND refers to the most flexible mode where textures with different opacity values are used. However blending is also the most expensive.
enum BlendType{
	NOBLEND,
	ALPHA = 0x1906,
	BLEND,
};
///Describes whether a model is going to be static or dynamic. Static models are usually not updated at all. Dynamic models are models which are updated often.
enum ModelType{
	STATIC = 0x88E4,
	DYNAMIC = 0x88E8,
};
///defines a vertex type
enum VertexType{
	VNT = 1,
	VT = 2,
	VN = 3,
	VC3 = 4,
	VC4 = 5,
	VC3T = 6,
	VC4T = 7,
};
///Perspective is the default where objects are rendered with a perspective. Ortho is used for objects which do not require a change in size based on distance from camera. Example uses of Ortho are fonts, HUDs, menus.
enum RenderMode{
	PERSPECTIVE,
	ORTHO,
};

enum TextureFormat{
	RGBA = 0x1908,
	RGB = 0x1907,
	RGB8 = 0x8051,
	COMPRESSED_RGBA_DXT1 = 0x83F1,
	COMPRESSED_RGB_DXT1 = 0x83F0,
	ALPHA8 = 0x803C,
	ALPHAX = 0x1906,
	INTENSITY8 = 0x804B,
};

///PassType defines the type of work the Pass will be doing thus allowing the Pass to be executed in the correct order. For example, things like rendering a shadowmap from the light's point of view or cubemaps for reflections can be categorised under PreProcess.Per-Pixel Lighting/Hardware Skinning can come under ACTUAL. Work which requires to be done after drawing has been done comes under POSTPROCESS.GUI is meant for GUI elements which are not meant to be affected by the postprocess effects.
enum PassType{
	PREPROCESS = 0,
	ACTUAL = 1,
	POSTPROCESS = 2,
	GUI = 3,
};

enum MouseEvent
{
	MOUSEMOVE,
	MOUSELEFTDOWN,
	MOUSERIGHTDOWN,
	MOUSEMIDDLEDOWN,
	MOUSELEFTUP,
	MOUSERIGHTUP,
	MOUSEMIDDLEUP,

};

///A function/method which which takes in an argument of MouseState& and returns void.
typedef boost::signal<void (MouseState& ms, MouseEvent me)> MouseUpdateReciever;
///OutputStream to a file
typedef std::ofstream OutputStream;
///InputStream to a file
typedef std::ifstream InputStream;
}
#endif

